<?php

class googleSearcher {
	private $cx;
	private $googleRequestURL;
	private $googleBaseURL = "http://www.google.com/custom";
	private $output = "xml_no_dtd";
	private $client = "google-csbe";
	private $ie = 'UTF-8';
	private $num = "10"; 
	private $start = "1";
	private $q;
	private $queryTime;
	private $numberResults;
	private $xmlResults;
	private $customResultFields;
	private $nextPage;
	private $prevPage;
	
	function __construct($cx) {
		$this->cx = $cx;
	}
	/**
	 * set the encoding of the results xml
	 * @param $ie the $ie to set
	 */
	public function setIe($ie) {
		$this->ie = $ie;
	}

	/**
	 * returns the encoding settings
	 * @return the $ie
	 */
	public function getIe() {
		return $this->ie;
	}

	/**
	 * returns a string representation of the previous page query
	 * used for retrieving the previous page of results from the current point in the index of results
	 * @return the $prevPage
	 */
	public function getPrevPage() {
		$xmlResults = $this->xmlResults;
		if(!(empty($xmlResults))){
			$prevPage = (string)$xmlResults->RES->NB->PU;
			$pos = strpos($prevPage,"start=0");
			if ($pos){
				$prevPage ='';
			} else {
				$prevPage = substr($prevPage,8);
			}
		} 
		return $prevPage;
	}

	/**
	 * returns a string representation of the next page query
	 * used for retrieving the next page of results from the current point in the index of results
	 * @return the $nextPage
	 */
	public function getNextPage() {
		$xmlResults = $this->xmlResults;
		if(!(empty($xmlResults))){
			$nextPage = (string)$xmlResults->RES->NB->NU;
			$nextPage = substr($nextPage,8);
		}
		return $nextPage;
	}

	/**
	 * @return the $numberResults
	 */
	public function getNumberResults() {
		$num=0;
		$xmlResults = $this->xmlResults;
		if(!(empty($xmlResults))){
			//parse the xml to get the number of results
			$num = $xmlResults->RES->M;
		}
		return $num;
	}

	/**
	 * @return the $queryTime
	 */
	public function getQueryTime() {
		$time=0;
		$xmlResults = $this->xmlResults;
		if(!(empty($xmlResults))){
			//parse the xml to get the querytime value
			$time = $xmlResults->TM;
		}
		return $time;
	}

	/**
	 * @param $customResultFields the $customResultFields to set
	 */
	public function setCustomResultFields($customResultFields) {
		$this->customResultFields = $customResultFields;
	}

	/**
	 * @return the $customResultFields
	 */
	public function getCustomResultFields() {
		return $this->customResultFields;
	}

	/**
	 * @param $xmlResults the $xmlResults to set
	 */
	public function setXmlResults($xmlResults) {
		$this->xmlResults = $xmlResults;
	}

	/**
	 * @return the $xmlResults
	 */
	public function getXmlResults() {
		return $this->xmlResults;
	}

	/**
	 * @param $googleRequestURL the $googleRequestURL to set
	 */
	public function setGoogleRequestURL($googleRequestURL) {
		$this->googleRequestURL = $googleRequestURL;
	}

	/**
	 * @return the $googleRequestURL
	 */
	public function getGoogleRequestURL() {
		return $this->googleRequestURL;
	}

	/**
	 * @param $q the $q to set the query for google
	 */
	public function setQ($q) {
		$this->q = $q;
	}

	/**
	 * @return the $q
	 */
	public function getQ() {
		return $this->$q;
	}

	/**
	 * @param $start the $start to set the starting position of the search results index
	 */
	public function setStart($start) {
		$this->start = $start;
	}

	/**
	 * @return the $start
	 */
	public function getStart() {
		return $this->start;
	}

	/**
	 * @param $num the $num to set the number of results per page, default is 10 results
	 */
	public function setNum($num) {
		$this->num = $num;
	}

	/**
	 * @return the $num
	 */
	public function getNum() {
		return $this->num;
	}

	/**
	 * @param $client the $client to set
	 */
	public function setClient($client) {
		$this->client = $client;
	}

	/**
	 * @return the $client
	 */
	public function getClient() {
		return $this->client;
	}

	/**
	 * @param $output the $output to set
	 */
	public function setOutput($output) {
		$this->output = $output;
	}

	/**
	 * @return the $output
	 */
	public function getOutput() {
		return $this->output;
	}

	/**
	 * @param $googleBaseURL the $googleBaseURL to set
	 */
	public function setgoogleBaseURL($googleBaseURL) {
		$this->googleBaseURL = $googleBaseURL;
	}

	/**
	 * @return the $googleBaseURL
	 */
	public function getGoogleBaseURL() {
		return $this->googleBaseURL;
	}

	/**
	 * @param $cx the $cx to set
	 */
	public function setCx($cx) {
		$this->cx = $cx;
	}

	/**
	 * @return the $cx
	 */
	public function getCx() {
		return $this->cx;
	}
	
	/**
	 * @exectues the search, requires $q (search term) as argument
	 */
	public function executeSearch($q) {
		$this->q = $q;
		$this->buildRequestURL(urlencode($q));
		$this->requestSearchXML();
		if(!(empty($this->xmlResults))){
			return 1;
		} else {
			return 0;
		}
	}
		
	/**
	 * @build the request url based on the $q search term
	 */
	private function buildRequestURL($q){
		$paramArray = array("cx" => $this->cx,
		"client" => $this->client,
		"output" => $this->output,
		"q" => $q,
		"ie" => $this->ie,
		"num" => $this->num,
		"start" => $this->start);
		//loop through and add all parameters to the base url
		$tempURL = $this->googleBaseURL;
		foreach ($paramArray as $param => $value){
			$tempURL = $this->addQueryParam($tempURL,$param,$value);
		}
		$this->setGoogleRequestURL($tempURL);
	}
	/**
	 * @get the results xml based on buildRequestURL method
	 */
	private function requestSearchXML(){
		$output = file_get_contents($this->googleRequestURL,1);        
        $xmlResults = simplexml_load_string($output);
        $this->xmlResults = $xmlResults;
	}
	/**
	 * returns an Array of results for display
	 */
	public function getResults(){
		//declare array to populate
		$results = array();
		if($this->getNumberResults() > 0){
			// get the xml results for the object, iterate through it to build the nice results array to return
			$resultsXML = $this->xmlResults;
			
			//loop through the results section of the xml results, and populate an associative array
			foreach ($resultsXML->RES->R as $searchResult) {	
				//add default search fields to fields array
				$resultsFieldsArray = array("title" => $searchResult->T,"summary" => $searchResult->S,"url" => $searchResult->U);
				//check for any custom fields to add
				if (!(empty($this->customResultFields))){
					//check to see if there is at least one value
					if(!(empty($searchResult->PageMap->DataObject->Attribute[0]['name']))){
						//check if its an array, simple xml make it an array only if more than one node
						if (count($searchResult->PageMap->DataObject->Attribute) > 1){
							foreach($searchResult->PageMap->DataObject->Attribute as $attribute){
								foreach($this->customResultFields as $name){
									if (strcmp($name,$attribute['name']) == 0){
										$nameKey = (string)$attribute['name'];
										$value = (string)$attribute['value'];
										$resultsFieldsArray[$nameKey] = $value;
									}
								}
							}
						} else {
							//only one value, so refer to it directly to compare
							foreach($this->customResultFields as $name){
								if (strcmp($name,$searchResult->PageMap->DataObject->Attribute[0]['name']) == 0){
									$nameKey = (string)$searchResult->PageMap->DataObject->Attribute[0]['name'];
									$value = (string)$searchResult->PageMap->DataObject->Attribute[0]['value'];
									$resultsFieldsArray[$nameKey] = $value;
								}
							}
						}
					}
				}
				//add to the array	
				array_push($results,$resultsFieldsArray);
			}
			return $results;
		}
		//no results, just return empty results
		return $results;
	}
	
	
	/**
	 * @add query parameters for request to google private function used only by the class
	 */
	private function addQueryParam($url,$key,$value) {
		$url = preg_replace('/(.*)(\?|&)' . $key . '=[^&]+?(&)(.*)/i', '$1$2$4', $url . '&');
		$url = substr($url, 0, -1);
		if (strpos($url, '?') === false) {
			return ($url . '?' . $key . '=' . $value);
		} else {
			return ($url . '&' . $key . '=' . $value);
		}
	}

}

?>